package com.one.pass.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;

@Slf4j  // 使用lombok的Slf4j注解，自动生成一个名为log的日志对象
public class JacksonUtil {

    // 自定义的Null值序列化器，当遇到Null值时将其序列化为JSON的null
    public static class NullSerializer extends JsonSerializer<Object> {
        public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
            jgen.writeNull();  // 将值序列化为null
        }
    }

    // 获取ObjectMapper实例
    public static ObjectMapper getObjectMapper() {
        return MyApplication.getBean(ObjectMapper.class);
    }

    // 将对象序列化为JSON字符串
    public static <T> String obj2Json(T obj) {
        try {
            return getObjectMapper().writeValueAsString(obj);  // 将对象序列化为JSON字符串
        } catch (IOException e) {
            log.error("对象序列化为JSON字符串出错", e);  // 序列化出错时记录日志
        }
        return null;
    }

    // 将JSON字符串反序列化为对象
    public static <T> T json2Obj(String json, Class<T> type) {
        try {
            return getObjectMapper().readValue(json, type);  // 将JSON字符串反序列化为对象
        } catch (IOException e) {
            log.error("JSON字符串反序列化为对象出错", e);  // 反序列化出错时记录日志
        }
        return null;
    }

    // 将JSON字符串反序列化为对象列表
    public static <T> List<T> json2List(String json, Class<T> type) {
        try {
            return getObjectMapper().readValue(json, getCollectionType(List.class, type));  // 将JSON字符串反序列化为对象列表
        } catch (Exception e) {
            log.error("JSON字符串反序列化为对象列表出错", e);  // 反序列化出错时记录日志
        }
        return null;
    }

    // 获取集合类型的JavaType对象
    private static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return getObjectMapper().getTypeFactory().constructParametricType(collectionClass, elementClasses);  // 构造集合类型的JavaType
    }
}
